package com.factory.aiclient.controller;

import com.alibaba.fastjson.JSONObject;
import com.factory.aiclient.feign.CameraClient;
import com.factory.aiclient.manager.SocketManager;
import com.factory.aiclient.util.SpringCtxUtils;
import com.factory.aiclient.webSocket.*;
import com.factory.common.pojo.Result;
import com.factory.common.pojo.SendData;
import com.factory.common.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;

/**
 * WebSocket 实现的视频播放控制器类
 *
 * @author JW
 * @version 1.0
 * @date 2020/12/3 11:24
 */
@ServerEndpoint("/aiclient/playback/{type}/{deviceId}/{cameraId}/{begin}/{end}")
@Controller
@Slf4j
@CrossOrigin
public class PlaybackController {

    private CameraClient cameraClient = SpringCtxUtils.getBean(CameraClient.class);

    @OnOpen
    public void onOpen(Session session, @PathParam(value = "type") String type, @PathParam(value = "deviceId") String deviceId,
                       @PathParam(value = "cameraId") String cameraId, @PathParam(value = "begin") Long begin
    ,@PathParam(value = "end") Long end) {
        //获取连接的用户
        log.info("加入session:{}", cameraId, type);
        Result result = cameraClient.query(cameraId, deviceId);
        if(!result.isStatus() || StringUtil.isEmpty(result.getData())){
            log.info("摄像头信息,{}",result.getData());
            closeSession(session, "摄像头不存在!");
        }
        session.setMaxTextMessageBufferSize(512000);
        switch (type) {
            case "read":
                if(!SocketManager.isOnLine(deviceId)){
                    log.warn("设备不在线关闭连接,{}",deviceId);
                    closeSession(session, "device not on line");
                }
                //开启终端写数据
                if(!PlaybackManager.hasWriter(cameraId)){
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("id",cameraId);
                    jsonObject.put("starttime",begin);
                    jsonObject.put("endtime",end);
                    Result liveCamera = SocketManager.sendSyncMessage(deviceId, new SendData(deviceId, StringUtil.getUUID(),"playback", jsonObject));
                    if(!liveCamera.isStatus()){
                        log.warn(liveCamera.getMessage() + ",关闭连接,{}",deviceId);
                        closeSession(session, liveCamera.getMessage());
                    }
                }

                PlaybackReader base64ImageWriter = new PlaybackReader(cameraId, session);
                PlaybackManager.setReader(session.getId(), base64ImageWriter);
                //开始写数据
                new Thread(base64ImageWriter).start();
                //需求数量加一
                PlaybackManager.addWriterForReaderNumber(cameraId);
                break;
            case "write":
                PlaybackManager.setWriter(cameraId, session);
                break;
            default:
                try {
                    session.close();
                } catch (IOException e) {
                    log.error("关闭session时发生异常,{}", e);
                }
                break;
        }
    }

    /**
     * 关闭session
     * @param session
     * @param message
     */
    private void closeSession(Session session, String message) {
        try {
            session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            log.error("发送数据时异常,{}",e);
        }
        try {
            session.close();
        } catch (IOException e) {
            log.error("关闭连接时异常,{}",e);
        }
    }

    @OnClose
    public void onClose(Session session) {
        log.info("移除不用的session:" + session.getId());
        PlaybackManager.removeSession(session);
    }

    //收到客户端信息
    @OnMessage
    public void onMessage(String message, Session session) throws IOException {
        log.debug("收到客户端信息,{}",session.getId());
        PlaybackPool.write(session, message);
    }

    //错误时调用
    @OnError
    public void onError(Session session, Throwable throwable) {
        log.error("webSocket 错误,{}", throwable);
        PlaybackManager.removeSession(session);
    }

}
